package juc;

import org.junit.Test;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * <pre>类名: ReadWriteLockTest</pre>
 * <pre>描述: 读写锁测试</pre>
 * <pre>版权: web_chen@163.com</pre>
 * <pre>日期: 2020/11/6 14:36</pre>
 * <pre>作者: chenwb</pre>
 */
public class ReadWriteLockTest {

	private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
	private ReentrantReadWriteLock.ReadLock rl = rwl.readLock();
	private ReentrantReadWriteLock.WriteLock wl = rwl.writeLock();

	/**
	 * 定义一个缓存
	 */
	private Map<String, Object> cache = new HashMap<>();

	/**
	 * 定义一个线程池
	 */
	private ThreadPoolExecutor executor = new ThreadPoolExecutor(20, 50, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(2000));

	public Object get(String key) {
		rl.lock();
		Object o;
		try {
			o = cache.get(key);
			if (o != null) {
				return o;
			}
		} finally {
			rl.unlock();
		}
		wl.lock();
		try {
			cache.put(key, getValFromDb());
			rl.lock();
		} finally {
			wl.unlock();
		}
		try {
			return o;
		} finally {
			rl.unlock();
		}
	}

	private Object getValFromDb() {
		return "mockData";
	}

	public Object set(String key, Object val) {
		wl.lock();
		try {
			return cache.put(key, val);
		} finally {
			wl.unlock();
		}
	}

	@Test
	public void testReadWriteLock() {
		long start = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			final int j = i;
			executor.execute(() -> get(Integer.toString(j)));
		}
		System.out.println("耗费时间：" + (System.currentTimeMillis() - start));
	}
}
